/*
JuffEd - A simple text editor
Copyright 2007 Murzin Mikhail

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License 
version 2 as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include "TextDoc.h"

//	Local
#include "HL.h"
#include "TextDocWidget.h"

//	Qt
#include <QtCore/QFile>
#include <QtCore/QTextCodec>
#include <QtGui/QTextDocument>

class TextDocInterior {
public:
	TextDocInterior(Document* doc, QWidget* parent) {
		doc_ = new QTextDocument();
		codec_ = QTextCodec::codecForLocale();
		widget_ = new TextDocWidget(doc, parent);
		widget_->setDocument(doc_);
		hl_ = new HL(doc_);
	}

	void read(const QString& fileName) {
		if (fileName.isEmpty())
			return;

		QFile file(fileName);
		if (file.open(QIODevice::ReadOnly)) {
			QString text = "";
			while (!file.atEnd()) {
				text += codec_->toUnicode(file.readLine());
			}
			doc_->setPlainText(text);
			file.close();
			hl_->changeFileName(fileName);
		}
	}
	bool write(const QString& fileName) {
		bool res = true;
		QFile file(fileName);
		if (file.open(QIODevice::WriteOnly)) {
			file.write(codec_->fromUnicode(doc_->toPlainText()));
			file.close();
			hl_->changeFileName(fileName);
			doc_->setModified(false);
		}
		else {
			res = false;
		}
		return res;
	}

	~TextDocInterior() {
		delete widget_;
		delete doc_;
	}

	QTextDocument* doc_;
	TextDocWidget* widget_;
	QTextCodec* codec_;
	HL* hl_;
};

TextDoc::TextDoc(const QString& name, QWidget* parent) : Document(name) {
	docInt_ = new TextDocInterior(this, parent);
	docInt_->read(name);
	applySettings();

	connect(docInt_->doc_, SIGNAL(modificationChanged(bool)), SIGNAL(modified(bool)));
	connect(docInt_->widget_, SIGNAL(cursorPositionChanged()), SIGNAL(cursorPosChanged()));
}

TextDoc::~TextDoc() {
	delete docInt_;
}

QWidget* TextDoc::widget() const {
	return docInt_->widget_;
}

int TextDoc::lineCount() const {
	return docInt_->doc_->blockCount();
}

bool TextDoc::save() {
	bool res = true;
	if (!fileName().isEmpty()) {
		res = docInt_->write(fileName());
	}
	else {
		res = false;
	}
	return res;
}

bool TextDoc::saveAs(const QString& name) {
	bool res = docInt_->write(name);
	if (res)
		setFileName(name);
	return res;
}

void TextDoc::applySettings() {
	docInt_->widget_->applySettings();
}

bool TextDoc::isModified() {
	return docInt_->doc_->isModified();
}

///////////////////////////////////////////////////////////////////////
//	Edit actions
///////////////////////////////////////////////////////////////////////

void TextDoc::cut() {
	docInt_->widget_->cut();
}

void TextDoc::copy() {
	docInt_->widget_->copy();
}

void TextDoc::paste() {
	docInt_->widget_->paste();
}

void TextDoc::undo() {
	docInt_->doc_->undo();
}

void TextDoc::redo() {
	docInt_->doc_->redo();
}

void TextDoc::setCharset(const QString& charset) {
	QTextCodec* codec = QTextCodec::codecForName(charset.toAscii());
	if (codec != 0) {
		docInt_->codec_ = codec;
		docInt_->read(fileName());
		docInt_->doc_->setModified(false);
	}
}

void TextDoc::find(const QString& str, bool matchCase, bool backwards) {
	docInt_->widget_->find(str, matchCase, backwards);
}

void TextDoc::gotoLine(int line) {
	docInt_->widget_->gotoLine(line);
}

void TextDoc::getCursorPos(int& row, int& col) {
	docInt_->widget_->getCursorPos(row, col);
}

QString TextDoc::charset() const {
	return docInt_->codec_->name();
}
